package dominio;

import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.util.Date;

import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

@Entity
@Table(name = "articulo")
@Inheritance
@DiscriminatorColumn(name = "categoria")
public abstract class Articulo implements Serializable {

	private static final long serialVersionUID = 8237307521640466307L;

	@Id
	private Long codigo;
	private String nombre;
	private String descripcion;
	private String marca;
	private Float precio;
	private String foto;
	private String origen;
	private Integer cantidad = 0;
	private Date fecha;

	public Articulo() {
		super();
		this.fecha = new Date();
	}

	public Articulo(Long codigo, String nombre, String descripcion,
			String marca, Float precio, String foto, String origen, Integer cantidad) {
		this();
		this.codigo = codigo;
		this.nombre = nombre;
		this.descripcion = descripcion;
		this.marca = marca;
		this.precio = precio;
		this.foto = foto;
		this.origen = origen;
		this.cantidad = cantidad;
	}

	public Articulo(String nombre, String descripcion, String marca,
			Float precio, String foto, String origen, Integer cantidad) {
		this();
		this.nombre = nombre;
		this.descripcion = descripcion;
		this.marca = marca;
		this.precio = precio;
		this.foto = foto;
		this.origen = origen;
		this.cantidad = cantidad;
	}

	public Long getCodigo() {
		return codigo;
	}

	public void setCodigo(Long codigo) {
		this.codigo = codigo;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public String getDescripcion() {
		return descripcion;
	}

	public void setDescripcion(String descripcion) {
		this.descripcion = descripcion;
	}

	public String getMarca() {
		return marca;
	}

	public void setMarca(String marca) {
		this.marca = marca;
	}

	public Float getPrecio() {
		return precio;
	}

	public void setPrecio(Float precio) {
		this.precio = precio;
	}

	public String getFoto() {
		return foto;
	}

	public void setFoto(String foto) {
		this.foto = foto;
	}

	public String getOrigen() {
		return origen;
	}

	public void setOrigen(String origen) {
		this.origen = origen;
	}
	
	public Date getFecha() {
		return fecha;
	}

	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}

	public String toXML() {
		String xmlFile = null;
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("articulo");
			doc.appendChild(rootElement);

			// codigo elements
			Element codigoElement = doc.createElement("codigo");
			Long codigo2 = getCodigo();
			String codigoString = codigo2 != null ? codigo2.toString() : "";
			codigoElement.appendChild(doc.createTextNode(codigoString));
			rootElement.appendChild(codigoElement);

			// idModulo elements
			Element idModulo = doc.createElement("idModulo");
			idModulo.appendChild(doc.createTextNode("11"));
			rootElement.appendChild(idModulo);
			
			// nombre elements
			Element nombreElement = doc.createElement("nombre");
			String nombre2 = getNombre() != null ? getNombre() : "";
			nombreElement.appendChild(doc.createTextNode(nombre2));
			rootElement.appendChild(nombreElement);

			// descripcion elements
			Element descripcionElement = doc.createElement("descripcion");
			String descripcion2 = getDescripcion() != null ? getDescripcion() : "";
			descripcionElement.appendChild(doc.createTextNode(descripcion2));
			rootElement.appendChild(descripcionElement);

			// marca elements
			Element marcaElement = doc.createElement("marca");
			String marca2 = getMarca() != null ? getMarca() : "";
			marcaElement.appendChild(doc.createTextNode(marca2));
			rootElement.appendChild(marcaElement);

			// precio elements
			Element precio = doc.createElement("precio");
			Float precio2 = getPrecio();
			String precioString = precio2 != null ? precio2.toString() : "";
			precio.appendChild(doc.createTextNode(precioString));
			rootElement.appendChild(precio);

			// origen elements
			Element origen = doc.createElement("origen");
			String origen2 = getOrigen() != null ? getOrigen() : "";
			origen.appendChild(doc.createTextNode(origen2));
			rootElement.appendChild(origen);

			// origen elements
			Element foto = doc.createElement("fotoURL");
			String foto2 = getFoto() != null ? getFoto() : "";
			foto.appendChild(doc.createTextNode(foto2));
			rootElement.appendChild(foto);
			
			// fecha elements FORMATO:YYYY-MM-DD hh:mm:ss -->
			Element fecha = doc.createElement("fecha");
			Date fecha2 = getFecha() != null ? getFecha() : new Date();
			java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String fechaString = sdf.format(fecha2);
			fecha.appendChild(doc.createTextNode(fechaString));
			rootElement.appendChild(fecha);

			addInformation(doc, rootElement);

			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory
					.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			// StreamResult result = new StreamResult(new File("C:\\file.xml"));
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			StreamResult result = new StreamResult(baos);

			// Output to console for testing
			// StreamResult result = new StreamResult(System.out);

			transformer.transform(source, result);
			System.out.println("File saved!");

			xmlFile = result.getOutputStream().toString();
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (TransformerException tfe) {
			tfe.printStackTrace();
		}

		return xmlFile;
	}

	public Integer getCantidad() {
		return cantidad;
	}
	
	public void aumentarStock(Integer valor) {
		cantidad = cantidad + valor;
	}
	
	public void descontarStock(Integer valor) {
		cantidad = cantidad - valor;
	}
	
	protected abstract void addInformation(Document doc, Element rootElement);

	@Override
	public String toString() {
		return "Articulo ["
				+ (codigo != null ? "codigo=" + codigo + ", " : "")
				+ (nombre != null ? "nombre=" + nombre + ", " : "")
				+ (descripcion != null ? "descripcion=" + descripcion + ", "
						: "") + (marca != null ? "marca=" + marca + ", " : "")
				+ (precio != null ? "precio=" + precio + ", " : "")
				+ (origen != null ? "origen=" + origen + ", " : "")
				+ (cantidad != null ? "cantidad=" + cantidad + ", " : "")
				+ (foto != null ? "foto=" + foto : "") + "]";
	}
	
	public abstract String getTipo();
}